package cn.iotab.iotkit.transport.mqtt.topic;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * TOPIC规则：
 * <p>
 * 设备 --> 平台 数据【平台订阅】
 * "/v1/device/post/platform/${productKey}/${deviceId}"
 * 设备 --> 平台 response【平台订阅】
 * "/v1/device/reply/platform/${productKey}/${deviceId}"
 * <p>
 * 平台 --> 设备 数据【设备订阅】
 * "/v1/platform/post/device/${productKey}/${deviceId}"
 * 平台 --> 设备 response【设备订阅】
 * "/v1/platform/reply/device/${productKey}/${deviceId}"
 */
public class MqttTopics {

    public enum TopicType {
        UNKNOWN,
        /**
         * 上行topic
         */
        DEVICE_POST_PLATFORM,
        DEVICE_REPLY_PLATFORM,
        /**
         * 下行topic
         */
        PLATFORM_POST_DEVICE,
        PLATFORM_REPLY_DEVICE
    }


    //上行数据topic前缀
    private static final String PREFIX_DEVICE_POST_PLATFORM = "/v1/device/post/platform/";
    //上行response topic前缀
    private static final String PREFIX_DEVICE_REPLY_PLATFORM = "/v1/device/reply/platform/";

    //下行数据topic前缀
    private static final String PREFIX_PLATFORM_POST_DEVICE = "/v1/platform/post/device/";
    //下行response topic前缀
    private static final String PREFIX_PLATFORM_REPLY_DEVICE = "/v1/platform/reply/device/";


    //上行数据topic正则
    private static final Pattern PATTERN_DEVICE_POST_PLATFORM = Pattern.compile("^" + PREFIX_DEVICE_POST_PLATFORM + "([0-9a-zA-Z_]+)/([0-9a-zA-Z_]+$)");
    //上行response topic正则
    private static final Pattern PATTERN_DEVICE_REPLY_PLATFORM = Pattern.compile("^" + PREFIX_DEVICE_REPLY_PLATFORM + "([0-9a-zA-Z_]+)/([0-9a-zA-Z_]+$)");

    //下行数据topic正则
    private static final Pattern PATTERN_PLATFORM_POST_DEVICE = Pattern.compile("^" + PREFIX_PLATFORM_POST_DEVICE + "([0-9a-zA-Z_]+)/([0-9a-zA-Z_]+$)");
    //下行response topic正则
    private static final Pattern PATTERN_PLATFORM_REPLY_DEVICE = Pattern.compile("^" + PREFIX_PLATFORM_REPLY_DEVICE + "([0-9a-zA-Z_]+)/([0-9a-zA-Z_]+$)");


    /**
     * 解析topic
     */
    public static TopicMeta parseTopic(String topic) {
        //无效Topic
        if (topic == null || topic.isEmpty()) {
            return TopicMeta.invalidTopic(topic);
        }
        //
        Matcher devicePostMatcher = PATTERN_DEVICE_POST_PLATFORM.matcher(topic);
        if (devicePostMatcher.matches()) {
            String productKey = devicePostMatcher.group(1);
            String deviceId = devicePostMatcher.group(2);
            return TopicMeta.validTopic(topic, TopicType.DEVICE_POST_PLATFORM, productKey, deviceId);
        }
        //
        Matcher deviceReplyMatcher = PATTERN_DEVICE_REPLY_PLATFORM.matcher(topic);
        if (deviceReplyMatcher.matches()) {
            String productKey = deviceReplyMatcher.group(1);
            String deviceId = deviceReplyMatcher.group(2);
            return TopicMeta.validTopic(topic, TopicType.DEVICE_REPLY_PLATFORM, productKey, deviceId);
        }
        //
        Matcher platformPostMatcher = PATTERN_PLATFORM_POST_DEVICE.matcher(topic);
        if (platformPostMatcher.matches()) {
            String productKey = platformPostMatcher.group(1);
            String deviceId = platformPostMatcher.group(2);
            return TopicMeta.validTopic(topic, TopicType.PLATFORM_POST_DEVICE, productKey, deviceId);
        }
        //
        Matcher platformReplyMatcher = PATTERN_PLATFORM_REPLY_DEVICE.matcher(topic);
        if (platformReplyMatcher.matches()) {
            String productKey = platformReplyMatcher.group(1);
            String deviceId = platformReplyMatcher.group(2);
            return TopicMeta.validTopic(topic, TopicType.PLATFORM_REPLY_DEVICE, productKey, deviceId);
        }
        //
        return TopicMeta.invalidTopic(topic);
    }

    /**
     * 构造下行数据topic
     */
    public static String buildDownPostTopic(String productKey, String deviceId) {
        return PREFIX_PLATFORM_POST_DEVICE + productKey + "/" + deviceId;
    }

    /**
     * 构造下行response topic
     */
    public static String buildDownReplyTopic(String productKey, String deviceId) {
        return PREFIX_PLATFORM_REPLY_DEVICE + productKey + "/" + deviceId;
    }

}
